#include "PasswordsModel.h"

#include <QInputDialog>
#include <QMessageBox>
#include <QUrl>

QString EncryptPassword(const QString &str)
{
    QByteArray xor1(QString("X!2$6*9(SKiasb+!v<.qF58_qwe~QsRTYvdeTYb").toUtf8());
    QString HEX("0123456789ABCDEF");
    wchar_t arr[256];
    memset(arr,0,sizeof(arr));
    int size = str.toWCharArray(arr);

    QString out;

    for (int i = 0; i < size && i < xor1.size(); i++)
    {
        arr[i] = arr[i] ^ xor1.at(i);
        for (int j=0; j<4; j++)
        {
            int m = arr[i] % 16;
            out.append( HEX[ m ]);
            arr[i] = arr[i] >> 4;
        }
    }

    return out;
}

QString DecryptPassword(const QString &str)
{
    QByteArray xor1 (QString("X!2$6*9(SKiasb+!v<.qF58_qwe~QsRTYvdeTYb").toUtf8());
    wchar_t arr[256];
    memset(arr,0,sizeof(arr));

    int cnt = 0;
    for(int i = 0; i < str.size(); i+=4)
    {
        for (int j = 0; j < 4 ; j++)
        {
            char c = str[i + j].toAscii();
            int v = 0;
            if (c >= '0' && c <= '9')
                v = c - '0';
            else
            if (c >= 'A' && c <= 'F')
                v = 10 + c - 'A';

            int val = ( v << (j * 4));
            arr[cnt] = arr[cnt] + val;
        }
        arr[cnt] = arr[cnt] ^ xor1[cnt];
        cnt++;
    }

    return QString::fromWCharArray(arr);
}

PasswordsModel::PasswordsModel(QObject *parent)
    : QAbstractTableModel(parent)
{
    m_data.beginGroup("AutoComplete");

    QString master = m_data.value(QLatin1String("Master")).toString();
    if ( master.length() > 0)
    {
        QString pwd = QInputDialog::getText((QWidget*)parent, tr("Master Password"), tr("Type a master password:"), QLineEdit::Password);
        if (pwd.length() == 0 || EncryptPassword(pwd) != master)
        {
            QMessageBox::warning((QWidget*)parent, tr("Warning"), tr("Invalid password!<br>No information will be displayed."));
            m_data.beginGroup(QLatin1String("fkgr"));
        }
    }
}

PasswordsModel::~PasswordsModel()
{
    m_data.endGroup();
}

QVariant PasswordsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role == Qt::SizeHintRole) {
        QFont font;
        font.setPointSize(10);
        QFontMetrics fm(font);
        int height = fm.height() + fm.height()/3;
        int width = fm.width(headerData(section, orientation, Qt::DisplayRole).toString());
        return QSize(width, height);
    }

    if (orientation == Qt::Horizontal) {
        if (role != Qt::DisplayRole)
            return QVariant();

        switch (section) {
            case 0:
                return tr("Web URL");
            case 1:
                return tr("User Name");
            case 2:
                return tr("Password");
            default:
                return QVariant();
        }
    }
    return QAbstractTableModel::headerData(section, orientation, role);
}

QVariant PasswordsModel::data(const QModelIndex &index, int role) const
{
    QStringList hosts = m_data.childGroups();
    if (index.row() < 0 || index.row() >= hosts.size())
        return QVariant();

    switch (role)
    {
        case Qt::DisplayRole:
        case Qt::EditRole:
        {
            QString host = hosts.at(index.row());
            switch (index.column())
            {
                case 0:
                    {
                        return QString(QByteArray::fromPercentEncoding( host.toUtf8() ));
                    }
                case 1:
                    {
                        QString user_control = m_data.value(host + "/form_username_control").toString();
                        QByteArray username = m_data.value(host + "/" + user_control).toByteArray();
                        return QUrl::fromPercentEncoding(username);
                    }
                case 2:
                    {
                        if (s_show_passwords)
                        {
                            QString pwd_control = m_data.value(host + "/form_password_control").toString();
                            QString pwd = DecryptPassword(QUrl::fromPercentEncoding(m_data.value(host + "/" + pwd_control).toByteArray()));
                            return pwd; //QString(QByteArray::fromPercentEncoding( pwd.toUtf8() ));
                        }
                        else
                            return QVariant();
                    }
            }
        }
        case Qt::FontRole:
        {
            QFont font;
            font.setPointSize(10);
            return font;
        }
    }

    return QVariant();
}

int PasswordsModel::columnCount(const QModelIndex &parent) const
{
    return (parent.isValid()) ? 0 : 3;
}

int PasswordsModel::rowCount(const QModelIndex &parent) const
{
    int size = m_data.childGroups().size();
    return (parent.isValid())  ? 0 : size;
}

bool PasswordsModel::removeRows(int row, int count, const QModelIndex &parent)
{
    if (parent.isValid())
        return false;

    int lastRow = row + count - 1;
    beginRemoveRows(parent, row, lastRow);
    QStringList lst = m_data.childGroups();
    for (int i = lastRow; i >= row; --i)
    {
        m_data.remove( lst.at(i) );
    }
    endRemoveRows();
    return true;
}
